home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Other / upsd / ups_folder / funcs.c.orig < prev    next >
Encoding:
Text File  |  1991-05-01  |  5.2 KB  |  324 lines

  1. /*
  2. **    f u n c s . c
  3. **
  4. **    functions for UPS monitor daemon
  5. **
  6. **    Arthur W. Neilson III
  7. **    art@pilikia.pegasus.com
  8. **    Sat Mar 30 1991
  9. */
  10.  
  11. #include "common.h"
  12.  
  13. /*
  14. **    g e t v a r s
  15. **
  16. **    retrieve environment variables
  17. */
  18. void
  19. getvars()
  20. {
  21.     char   *s, *getenv();
  22.  
  23.     if ((s = getenv(UPSPORT)) != NULL)
  24.         ups_port = s;
  25.     if ((s = getenv(UPSSHUT)) != NULL)
  26.         ups_shut = s;
  27.     if ((s = getenv(UPSLOG)) != NULL)
  28.         ups_log = s;
  29.     if ((s = getenv(UPSTIME)) != NULL)
  30.         ups_time = atoi(s);
  31. }
  32.  
  33. /*
  34. **    g e t o p t i o n s
  35. **
  36. **    retrieve and process command line options
  37. */
  38. void
  39. getoptions(ac, av)
  40. int     ac;
  41. char   *av[];
  42. {
  43.     int     c;
  44.  
  45.     void    version();
  46.     void    usage();
  47.  
  48.     extern char *optarg;
  49.     extern int optind, opterr;
  50.  
  51.     /* display program version */
  52.     version(av[0]);
  53.  
  54.     /* parse the command line */
  55.     while ((c = getopt(ac, av, "d:c:l:t:")) != EOF)
  56.         switch (c) {
  57.         case 'd':    /* device option */
  58.             ups_port = optarg;
  59.             break;
  60.         case 'c':    /* command option */
  61.             ups_shut = optarg;
  62.             break;
  63.         case 'l':    /* logfile option */
  64.             ups_log = optarg;
  65.             break;
  66.         case 't':    /* time option */
  67.             ups_time = atoi(optarg);
  68.             break;
  69.         case '\?':    /* illegal option */
  70.             usage(av[0]);
  71.             exit(1);
  72.         }
  73. }
  74.  
  75. /*
  76. **    c h k o p t i o n s
  77. **
  78. **    check runtime options
  79. */
  80. void
  81. chkoptions()
  82. {
  83.     struct stat st;
  84.     char   *p, buf[64];
  85.  
  86.     /* UPS port must exist */
  87.     if (stat(ups_port, &st) == ERR) {
  88.         perror(ups_port);
  89.         exit(1);
  90.     }
  91.     /* and must be character special */
  92.     if ((st.st_mode & S_IFMT) != S_IFCHR) {
  93.         fprintf(stderr, "%s not character special\n", ups_port);
  94.         exit(1);
  95.     }
  96.     /* get command name out of shutdown command */
  97.     strcpy(buf, ups_shut);
  98.     if ((p = strtok(buf, " ")) == NULL)
  99.         p = buf;
  100.  
  101.     /* shutdown command must exist */
  102.     if (stat(p, &st) == ERR) {
  103.         perror(ups_shut);
  104.         exit(1);
  105.     }
  106.     /* and must be readable/executable by owner */
  107.     if (!(st.st_mode & SHUT_PERMS)) {
  108.         fprintf(stderr, "%s must be readable/executable by owner\n", ups_port);
  109.         exit(1);
  110.     }
  111.     /* delay time must be > 0 and <= MAX_TIME */
  112.     if (ups_time < 1 || ups_time > MAX_TIME) {
  113.         fprintf(stderr, "time must be between 1 and %d\n", MAX_TIME);
  114.         exit(1);
  115.     }
  116. }
  117.  
  118. /*
  119. **    m k d a e m o n
  120. **
  121. **    create daemon process
  122. */
  123. void
  124. mkdaemon()
  125. {
  126.     char    c;
  127.  
  128.     void    sigcatch();
  129.     void    writelog();
  130.     void    shutdown();
  131.  
  132.     if (!fork()) {
  133.  
  134.         /* close standard files */
  135.         close(0);    /* stdin */
  136.         close(1);    /* stdout */
  137.         close(2);    /* stderr */
  138.  
  139.         setpgrp();    /* disassociate from terminal */
  140.  
  141.         /* ignore interrupts */
  142.         signal(SIGHUP, SIG_IGN);
  143.         signal(SIGINT, SIG_IGN);
  144.         signal(SIGQUIT, SIG_IGN);
  145.  
  146.         /* catch termination signal */
  147.         signal(SIGTERM, sigcatch);
  148.  
  149.         /* and shutdown on alarm */
  150.         signal(SIGALRM, shutdown);
  151.  
  152.         /* open log file for append */
  153.         if ((log_fd = open(ups_log, LOG_FLAGS, LOG_PERMS)) == ERR)
  154.             exit(1);
  155.  
  156.         /* and advisory lock it */
  157.         if (lockf(log_fd, F_TLOCK, 0L) == ERR)
  158.             exit(1);
  159.  
  160.         writelog(START_MSG);
  161.  
  162.         /* open blocks on UPS switch to battery */
  163.         if ((ups_fd = open(ups_port, O_RDWR)) == ERR) {
  164.             writelog(OPEN_MSG);
  165.             exit(1);
  166.         }
  167.         writelog(BATTERY_MSG);
  168.  
  169.         /* set the alarm clock */
  170.         alarm(ups_time * SECS_PER_MIN);
  171.  
  172.         /* read blocks on UPS switch to online */
  173.         if (read(ups_fd, &c, 1) == ERR)
  174.             exit(1);
  175.  
  176.         writelog(ONLINE_MSG);
  177.  
  178.         close(log_fd);
  179.         close(ups_fd);
  180.  
  181.         mkdaemon();
  182.     }
  183. }
  184.  
  185. /*
  186. **    s i g c a t c h
  187. **
  188. **    catch termination signal
  189. */
  190. void
  191. sigcatch()
  192. {
  193.     writelog(TERM_MSG);
  194.     close(log_fd);
  195.     close(ups_fd);
  196.     exit(1);
  197. }
  198.  
  199. /*
  200. **    w r i t e l o g
  201. **
  202. **    write message to the UPS log file
  203. */
  204. void
  205. writelog(msg)
  206. char   *msg;
  207. {
  208.     time_t  ticks;
  209.     char   *p, *ct;
  210.     char    msg_buf[80];
  211.  
  212.     time(&ticks);
  213.     ct = ctime(&ticks);
  214.  
  215.     /* find newline in buffer */
  216.     if ((p = strrchr(ct, '\n')) != NULL)
  217.         *p = NULL;    /* and zap it */
  218.  
  219.     sprintf(msg_buf, "%s -- %s\n", ct, msg);
  220.     write(log_fd, msg_buf, strlen(msg_buf));
  221. }
  222.  
  223. /*
  224. **    s h u t d o w n
  225. **
  226. **    shutdown the system
  227. */
  228. void
  229. shutdown()
  230. {
  231.     void    attach();
  232.  
  233.     writelog(SHUTDOWN_MSG);
  234.  
  235.     close(log_fd);
  236.     close(ups_fd);
  237.  
  238.     attach(CONSOLE);
  239.  
  240.     chdir(ROOT);
  241.  
  242.     /* execute shutdown command */
  243.     execlp(SH, SH, "-c", ups_shut, NULL);
  244. }
  245.  
  246. /*
  247. **    a t t a c h
  248. **
  249. **    attach standard i/o to a device
  250. */
  251. void
  252. attach(dev)
  253. char   *dev;
  254. {
  255.     int     fd;
  256.  
  257.     /* close standard files */
  258.     close(0);        /* stdin */
  259.     close(1);        /* stdout */
  260.     close(2);        /* stderr */
  261.  
  262.     /* attach stdin to named device */
  263.     if ((fd = open(dev, O_RDWR)) == ERR)
  264.         exit(1);
  265.     dup(fd);        /* and stdout */
  266.     dup(fd);        /* and stderr */
  267. }
  268.  
  269. /*
  270. **    b a s e n a m e
  271. **
  272. **    remove absolute path from filename
  273. **
  274. */
  275. char   *
  276. basename(s)
  277. char   *s;
  278. {
  279.     register char *p;
  280.  
  281.     /* point to char after last '/' */
  282.     if ((p = strrchr(s, '/')) != NULL)
  283.         return (++p);
  284.  
  285.     return (s);
  286. }
  287.  
  288. /*
  289. **    v e r s i o n
  290. **
  291. **    display program version
  292. */
  293. void
  294. version(s)
  295. char   *s;
  296. {
  297.     char   *basename();
  298.  
  299.     /* display version in foreground */
  300.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  301.         fprintf(stderr, "%s release %s version %d.%d patchlevel %d\n",
  302.             basename(s), RELEASE_DATE, RELEASE, REVISION,
  303.             PATCHLEVEL);
  304. }
  305.  
  306. /*
  307. **    u s a g e
  308. **
  309. **    display program usage
  310. */
  311. void
  312. usage(s)
  313. char   *s;
  314. {
  315.     char   *basename();
  316.  
  317.     fprintf(stderr, "usage: %s [-d tty][-c cmd][-l log][-t min][-v]\n",
  318.         basename(s));
  319.     fprintf(stderr, "\t-d tty\t\tpathname of UPS device\n");
  320.     fprintf(stderr, "\t-c cmd\t\tpathname of shutdown command\n");
  321.     fprintf(stderr, "\t-l log\t\tpathname of UPS log file\n");
  322.     fprintf(stderr, "\t-t min\t\tdelay time in minutes\n");
  323. }
  324.